Here are is an example for Visual C++ and C# that demonstrates combining encryption and compression entirely in memory in a single pass. It shows how to use the Rijndael algorithm and the GZip compression format to encrypt compressed data and, then reverse the process.
// This code uses the #import directive. The components don't have a DLL-API.
// Import the COM interface of Xceed Encryption for COM/ActiveX
#import "XceedCry.dll" no_namespace named_guids
/* Both Xceed Encryption for COM/ActiveX and Xceed Streaming Compression for COM/ActiveX
component define an interface called IXceedProcessData that allow the components to
exchange data. When using both components at the same time, this will cause a naming
conflict with the compiler. To solve, that, we will instruct the second component
that is imported to exclude the interface to avoid the conflict. */// Import the COM interface of Xceed Streaming Compression for COM/ActiveX
#import "XceedSco.dll" no_namespace named_guids exclude("IXceedProcessData")
void CompressEncrypt1()
{
CoInitialize( NULL );
try
{
// Create and license a streaming compression control object
IXceedStreamingCompressionPtr compression;
compression.CreateInstance( CLSID_XceedStreamingCompression );
compression->License( _bstr_t( YourStreamingCompressionLicenseKey ) );
// Create and setup a GZip compression object
IXceedGZipCompressionFormatPtr gzip;
gzip.CreateInstance( CLSID_XceedGZipCompressionFormat );
// Create and license an encryption control object
IXceedEncryptionPtr encryption;
encryption.CreateInstance( CLSID_XceedEncryption );
encryption->License( _bstr_t( YourEncryptionLicenseKey ) );
// Create and setup a rijndael (AES) encryption object
IXceedRijndaelEncryptionMethodPtr rijndael;
rijndael.CreateInstance( CLSID_XceedRijndaelEncryptionMethod );
rijndael->SetSecretKeyFromPassPhrase( "This is a weak pass phrase!", 128 );
/* Order is important. We want to compress data before we encrypt it. So we will assign
the compression as a sub processor to the encryption. This will have the effect that the
encryption will ask the compression object to process the data BEFORE it encrypts. */// Link the encryption object with the compression object
rijndael->SubProcessing = IXceedProcessDataPtr( gzip );
// Assign the encryption object to the encryption control so we can perform operations on it
encryption->EncryptionMethod = IXceedEncryptDataPtr( rijndael );
// Set up data to compress/encrypt
constchar * pszSource = "This is the data to encrypt";
DWORD dwSourceSize = lstrlenA( pszSource ) + 1; // Let's say we want to encrypt the null-char too
// Setup variables to receive the encrypted data
BYTE * pcEncrypted = NULL;
DWORD dwEncryptedSize = 0;
// Compress/encrypt the data
encryption->Encrypt( ( BYTE* ) pszSource, dwSourceSize, TRUE, &pcEncrypted, &dwEncryptedSize );
/* TODO: Store the encrypted data somewhere */
BYTE * dataStore = new BYTE[ dwEncryptedSize ];
memcpy( dataStore, pcEncrypted, dwEncryptedSize );
// It is important to release the memory used by the encrypted data to avoid memory leaks
CoTaskMemFree( pcEncrypted );
/* .... *//* To decrypt/decompress, we setup the objects exactly like you would for compression/encryption.
But we will use the Decrypt() method instead. The method will perform SubProcessing by
decrypting FIRST, and then sending the data for decompression. */// Setup variables to receive the decrypted data
BYTE* pcDecrypted = NULL;
DWORD dwDecryptedSize = 0;
// Decrypt/decompress the data
encryption->Decrypt( ( BYTE* ) dataStore, dwEncryptedSize, TRUE, &pcDecrypted, &dwDecryptedSize );
// Reconstitute the original data
char * pszReconstitutedSource = ( char * ) pcDecrypted;
// Release the memory used by the decrypted data
CoTaskMemFree( pcDecrypted );
// Release the data store memory we used
delete[] dataStore;
}
catch( const _com_error& xErr )
{
WCHAR szMsg[50];
wsprintf( szMsg, L"Error %08x\n", xErr.Error() );
OutputDebugString( szMsg );
}
catch( ... )
{
OutputDebugString( L"Unknown error" );
}
CoUninitialize();
}
using XceedEncryptionLib;
using XceedStreamingCompressionLib;
namespace CSharpExamples
{
publicclass CompressEncrypt1
{
publicstaticvoid Example()
{
bool licensed;
// Create and license a streaming compression control object
XceedStreamingCompression compression = new XceedStreamingCompressionClass();
licensed = compression.License( CSharpExamples.YourStreamingCompressionLicenseKey );
// Create and setup a GZip compression object
XceedGZipCompressionFormat gzip = new XceedGZipCompressionFormatClass();
// Create and license an encryption control object
XceedEncryption encryption = new XceedEncryptionClass();
licensed = encryption.License( CSharpExamples.YourEncryptionLicenseKey );
// Create and setup a rijndael (AES) encryption object
XceedRijndaelEncryptionMethod rijndael = new XceedRijndaelEncryptionMethodClass();
rijndael.SetSecretKeyFromPassPhrase( "This is a weak pass phrase!", 128 );
/* Order is important. We want to compress data before we encrypt it. So we will assign
the compression as a sub processor to the encryption. This will have the effect that the
encryption will ask the compression object to process the data BEFORE it encrypts. */// Link the encryption object with the compression object
rijndael.SubProcessing = ( XceedEncryptionLib.IXceedProcessData ) gzip;
// Assign the encryption object to the encryption control so we can perform operations on it
encryption.EncryptionMethod = ( IXceedEncryptData ) rijndael;
// Set up data to compress/encrypt
string source = "This is the data to encrypt";
byte[] sourceBytes = Encoding.UTF8.GetBytes( source );
object sourceObject = sourceBytes;
// Setup variables to receive the encrypted data
object encryptedObject = null;
// Compress/encrypt the data
encryptedObject = encryption.Encrypt( ref sourceObject, true );
/* TODO: Store the encrypted data somewhere */byte[] encryptedBytes = ( byte[] ) encryptedObject;
/* .... *//* To decrypt/decompress, we setup the objects exactly like you would for compression/encryption.
But we will use the Decrypt() method instead. The method will perform SubProcessing by
decrypting FIRST, and then sending the data for decompression. */// Setup variables to receive the decrypted data
encryptedObject = encryptedBytes;
object decryptedObject;
// Decrypt/decompress the data
decryptedObject = encryption.Decrypt( ref encryptedObject, true );
// Reconstitute the original data
byte[] decryptedBytes = ( byte[] ) decryptedObject;
string reconstitutedSource = Encoding.UTF8.GetString( decryptedBytes );
}
}
}